package work.huangxin.share.service.impl;

import io.minio.*;
import io.minio.errors.*;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FilenameUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import work.huangxin.share.config.MinioConfig;
import work.huangxin.share.service.ISysFileService;
import work.huangxin.share.util.StringUtils;
import work.huangxin.share.util.file.DateUtils;
import work.huangxin.share.util.file.FileTypeUtils;
import work.huangxin.share.util.file.Seq;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * Minio 文件存储
 *
 * @author 张锦标
 */
@Service
@Primary
public class MinioSysFileServiceImpl implements ISysFileService {
    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private OssServiceImpl ossService;

//    @Autowired
//    private

//    @Value("${local:file:path}")
//    public static final String PREFIX_PATH = "D:/desktophoto/file/";
    public static final String PREFIX_PATH = "/opt/software/images/";
    /**
     * 编码文件名
     */
    public static final String extractFilename(MultipartFile file) {
        return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
                FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType),"jpg");
    }

    /**
     * 本地文件上传接口
     *
     * @param file 上传的文件
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        String fileName = extractFilename(file);
        //判断桶是否存在
        boolean found =
                minioClient.bucketExists(BucketExistsArgs.builder()
                        .bucket(minioConfig.getBucketName()).build());
        if (found) {
            InputStream is = file.getInputStream();
            //为当前文件创建目录
            String path = PREFIX_PATH+fileName;
            String dir = path.substring(0, path.lastIndexOf("/"));
            File fileDir = new File(dir);
            fileDir.mkdirs();
            //压缩后的文件位置
            Thumbnails.of(is)
                    .scale(0.5)
                    .outputFormat("webp")
                    .toFile(path);
            FileInputStream fis = new FileInputStream(path+".webp");
            System.out.println("my-bucketname exists");
            PutObjectArgs args = PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName()) //设定桶名称
                    .object(fileName+".webp") //要下载的文件
                    .stream(fis, fis.available(), -1) //文件上传流
                    .contentType(file.getContentType()) //设定文件类型
                    .build();
            //上传文件
            minioClient.putObject(args);
            is.close();
            fis.close();
            //return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
            return fileName;
        } else {
            System.out.println("my-bucketname does not exist");
            throw new RuntimeException("my-bucketname " + minioConfig.getBucketName()
                    + " does not exist");
        }
    }

    /**
     * 获取文件 用于文件回显
     *
     * @param name 文件在minio中的路径
     * @return
     * @throws Exception
     */
    public GetObjectResponse getFile(String name) throws Exception {
        GetObjectArgs getObjectArgs = GetObjectArgs
                .builder()
                .bucket(minioConfig.getBucketName())
                .object(name) //
                .build();
        return minioClient.getObject(getObjectArgs);
    }


    /**
     * 根据图片的url删除图片
     *
     * @param photoUrls 二手商品对象的url
     */
    public void deleteFiles(String photoUrls) throws ServerException, InsufficientDataException,
            ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException,
            InvalidResponseException, XmlParserException, InternalException {
        boolean found =
                minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioConfig.getBucketName()).build());
        if (found) {

            String[] names = photoUrls.split(",");
            for (String name : names) {
                try {
                    RemoveObjectArgs removeObjectsArgs =
                            RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(name).build();
                    minioClient.removeObject(removeObjectsArgs);
                } catch (Exception e){
                    throw new RuntimeException(e);
                }
            }
        }else{
            throw new RuntimeException("Minio中并没有这个桶:"+minioConfig.getBucketName());
        }
    }
    public String uploadFileWithZip(MultipartFile file) throws Exception {
        String fileName = extractFilename(file);
        //判断桶是否存在
        boolean found =
                minioClient.bucketExists(BucketExistsArgs.builder()
                        .bucket(minioConfig.getBucketName()).build());
        if (found) {
            InputStream is = file.getInputStream();
            //为当前文件创建目录
            String path = PREFIX_PATH+fileName;
            String dir = path.substring(0, path.lastIndexOf("/"));
            File fileDir = new File(dir);
            fileDir.mkdirs();
            //压缩后的文件位置
            Thumbnails.of(is)
                    .scale(0.75)
//                    .outputFormat("webp")
//                    .outputFormat("jpg")
//                    .outputFormat("webp")
                    .toFile(path);
            File outZipImage = new File(path);
            FileInputStream fis = new FileInputStream(path);
            System.out.println("my-bucketname exists");
//            PutObjectArgs args = PutObjectArgs.builder()
//                    .bucket(minioConfig.getBucketName()) //设定桶名称
//                    .object(fileName) //要下载的文件
//                    .stream(fis, fis.available(), -1) //文件上传流
//                    .contentType(file.getContentType()) //设定文件类型
//                    .build();
            //上传文件
//            minioClient.putObject(args);
            String ossImageUrl = ossService.uploadImage(fileName, outZipImage);
            is.close();
            fis.close();
            //return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
            return ossImageUrl;
        } else {
            System.out.println("my-bucketname does not exist");
            throw new RuntimeException("my-bucketname " + minioConfig.getBucketName()
                    + " does not exist");
        }
    }
}
